import numpy as np
from scipy.fftpack import fft

class feature_extraction:

    def __init__(self, frame):
        self.frame = frame
        self.N = len(self.frame)
        self.fft_y = np.zeros((self.N,))
        self.power = np.zeros((self.N,))
        self.mag = 0

    # get 4 feature
    def get_4_feature(self):
        IEMG = self.get_MAV
        AEMG = self.get_AEMG
        RMS = self.get_RMS
        self.get_fft_value()
        self.get_power()
        MPF = self.get_MNF
        return IEMG, AEMG, RMS, MPF

    # get feature
    def get_feature(self):
        MAV = self.get_MAV
        VAR = self.get_VAR
        ZC = self.get_ZC
        RMS = self.get_RMS
        WA = self.get_WA()
        self.get_fft_value()
        self.get_power()
        MNP = self.get_MNP
        MNF = self.get_MNF
        MF = self.get_MF
        AEMG = self.get_AEMG
        return MAV, VAR, ZC, RMS, WA, MNP, MNF, MF

    # sgn function
    @staticmethod
    def sgn_function(value):
        sgn_array = []
        for v in value:
            if v < 0:
                sgn_array.append(1)
            else:
                sgn_array.append(0)
        return sgn_array

    # AEMG
    @property
    def get_AEMG(self):
        return np.mean(self.frame);

    # Mean absolute value, MAV(IEMG)
    @property
    def get_MAV(self):
        return np.mean(np.abs(self.frame))

    # Variance, VAR
    @property
    def get_VAR(self):
        return np.var(self.frame)

    # Root mean square, RMS
    @property
    def get_RMS(self):
        mean_frame = np.mean(self.frame)
        value = np.sum((self.frame-mean_frame)*self.frame-mean_frame)/self.N
        return np.sqrt(value)

    # 过零数, ZC
    @property
    def get_ZC(self):
        value = self.frame[:self.N-1]*self.frame[1:]
        value_transform = self.sgn_function(value)
        return np.sum(value_transform)

    # Willison幅值, WA
    def get_WA(self):
        value = self.frame[:self.N-1] - self.frame[1:]
        value_transform = self.sgn_function(value)
        return np.sum(value_transform)

    # 快速傅里叶变换
    def get_fft_value(self):
        self.fft_y = fft(self.frame)

    # 功率谱
    def get_power(self):
        self.mag = np.abs(self.fft_y)
        self.power = self.mag**2/2

    # Mean power, MNP
    @property
    def get_MNP(self):
        return np.sum(self.power)/self.N

    # Mean Frequency, MNF
    @property
    def get_MNF(self):
        power = self.mag**2/self.N
        ss = np.sum(power)
        M2 = 0.5*ss
        df = 1000/self.N
        M1 = 0.5*df*(np.sum(power[0:-1])+np.sum(power[1:]))
        return M1/M2
        # frame_freq = np.linspace(20, 500, self.N)
        # return np.sum(frame_freq*self.power)/np.sum(self.power)

    # Median Frequency, MF
    @property
    def get_MF(self):
        ss = np.sum(self.power)
        return ss/4

